package com.ff.xyh.service.userfront.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ff.xyh.common.entity.userfront.FrontUser;
import com.ff.xyh.common.vo.user.UserBaseInfo;
import com.ff.xyh.common.utils.JwtUtils;
import com.ff.xyh.common.utils.MD5;
import com.ff.xyh.common.entity.result.ResultMessage;
import com.ff.xyh.common.entity.result.ResultObject;

import com.ff.xyh.service.userfront.service.FrontUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <p>
 * 前端用户表 前端控制器
 * </p>
 *
 * @author ff
 * @since 2022-10-25
 */
@RestController
@RequestMapping("/front-user")
public class FrontUserController {

    @Autowired
    private FrontUserService frontUserService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 登录 前端需要把token写入cookie 发送请求时作为请求头
     * @param userToken
     * @param password
     * @return
     */
    @PostMapping("login")
    public ResultObject login(
            @RequestParam(name = "userToken", required = false) String userToken,
            @RequestParam(name = "password", required = false) String password) {
        FrontUser frontUser = frontUserService.login(userToken, password);
        if (frontUser != null) {
            String token = frontUserService.createTokenWithUserId(frontUser.getId());
//            上面的方法已经将token存入 FrontUserService::userId
//            redisTemplate.opsForValue().set(frontUser.getId(), token);
            return ResultObject.ok().data("token", token);
        } else
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
    }

    @PostMapping("login-token")
    public ResultObject loginWithToken(
            @RequestParam(name = "token") String token) {
        if (StringUtils.isEmpty(token))
            return ResultObject.error().message("请求头不存在token");
        String userId = JwtUtils.getSubjectFromToken(token);
        if (StringUtils.isEmpty(userId))
            return ResultObject.error().message("token非法");
        String existToken = (String) redisTemplate.opsForValue().get(
                "FrontUserService::" + userId);
        if (StringUtils.isEmpty(existToken))
            return ResultObject.error().message("服务器token不存在");
        if (token.equals(existToken)){ // token 与 服务器的token相同
            // 检查token是否需要更新
            token = JwtUtils.checkToken(token);
            if (! token.equals(existToken)) // token被更新了 则也更新到redis
                redisTemplate.opsForValue().set(
                        "FrontUserService::" + userId, token);
            return ResultObject.ok().data("token", token);
        } else {
            return ResultObject.error().message("token非法");
        }

    }


    /**
     * 注册
     * @param frontUser
     * @return
     */
    @PostMapping("register")
    public ResultObject register (
            @RequestBody(required = false) FrontUser frontUser) {
        if (frontUserService.getById(frontUser.getId()) == null) {
            frontUser.setPassword(MD5.encrypt(frontUser.getPassword()));
            if (frontUserService.save(frontUser)) {
                frontUser.setPassword(""); // 置空
                Map map = new HashMap();
//                String token = JwtUtils.createUserJwtToken(
//                        frontUser.getId(),
//                        frontUser.getNickname(),
//                        frontUser.getAvatar(),
//                        frontUser.getSex()
//                );
                String token = JwtUtils.createJwtTokenWithUserId(frontUser.getId());
                redisTemplate.opsForValue().set(
                        "FrontUserService::" + frontUser.getId(), token);
                map.put("data", frontUser);
                map.put("token", token); // 可以用于直接登录
                return ResultObject.ok().data(map);
            } else{

                return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT_BUT_FAILED_TO_INSERT);
            }
        } else {
            return ResultObject.error().message(ResultMessage.OBJECT_ALREADY_EXISTS);
        }
    }


//    /**
//     * 通过token查询用户基本信息
//     * @param request
//     * @return
//     */
//    @GetMapping("get-user-request")
//    public ResultObject getUserBaseInfo (HttpServletRequest request) {
//        String jwtToken = request.getHeader("token");
//        return getUserBaseInfo(jwtToken);
//    }
//    @GetMapping("get-user-token")
//    public ResultObject getUserBaseInfo (String token) {
//        UserBaseInfo userBaseInfo = new UserBaseInfo();
//        try {
//            userBaseInfo.setId((String) JwtUtils.getValueInJwtToken(token, "id"))
//                    .setNickname((String) JwtUtils.getValueInJwtToken(token, "nickname"))
//                    .setAvatar((String) JwtUtils.getValueInJwtToken(token, "avatar"))
//                    .setSex((Integer) JwtUtils.getValueInJwtToken(token, "sex"));
//        } catch (NullPointerException e) {
//            throw new MyException(20001, "token取不到值");
//        }
//        userBaseInfo.setToken(token);
//        Map map = new HashMap();
//        map.put("user", userBaseInfo);
//        return ResultObject.ok().data(map);
//    }


    /**
     * 通过openid获取对象
     * @param openid
     * @return
     */
    @GetMapping("get-user-open-id")
    public ResultObject getUserByOpenid (
            @RequestParam(name = "openid") String openid) {
        return frontUserService.getUserByOpenid(openid);
    }

    @GetMapping("get-user-base-id")
    ResultObject getUserBaseInfoById(@RequestParam(name = "id") String id ) {
        FrontUser frontUser = frontUserService.getById(id);
        if (frontUser != null) {
            UserBaseInfo userBaseInfo = new UserBaseInfo();
            BeanUtils.copyProperties(frontUser, userBaseInfo);
            return ResultObject.ok().data("data", userBaseInfo);
        } else {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
    }

    /**
     * 通过 ids 批量获取用户基本信息
     * @param userIds
     * @return
     */
    @GetMapping("get-user-base-ids")
    ResultObject getUserBaseInfosByIds(
            @RequestParam(name = "ids") List<String> userIds ) {
        Collection<FrontUser> frontUsers = frontUserService.listByIds(userIds);
        if (frontUsers == null || frontUsers.isEmpty()) {
            return ResultObject.ok().message(ResultMessage.NO_RESULT);
        } else {
            List<UserBaseInfo> resultList = new ArrayList<>();
            for (FrontUser frontUser : frontUsers) {
                UserBaseInfo userBaseInfo = new UserBaseInfo();
                BeanUtils.copyProperties(frontUser, userBaseInfo);
                resultList.add(userBaseInfo);
            }
            return ResultObject.ok().data("items", resultList);
        }
    }
//    @GetMapping("get-user-base-id")
//    public ResultObject getUserBaseInfoById (String token) {
//        String userId = JwtUtils.getSubjectFromToken(token);
//        FrontUser frontUser = frontUserService.getById(userId);
//        if (frontUser != null) {
//            UserBaseInfo userBaseInfo = new UserBaseInfo();
//            BeanUtils.copyProperties(frontUser, userBaseInfo);
//            userBaseInfo.setToken(token);
//            return ResultObject.ok().data("data", userBaseInfo);
//        } else {
//            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
//        }
//    }

    /**
     * 通过id查询用户所有信息
     * @param id
     * @return
     */
    @GetMapping("get-user-id")
    public ResultObject getUserById (
            @RequestParam(name = "id", required = false) String id ) {
        FrontUser frontUser = frontUserService.getById(id);
        if (frontUser != null) {
            frontUser.setPassword("");
            return ResultObject.ok().data("data", frontUser);
        } else {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
    }
    @GetMapping("get-user-username")
    public ResultObject getUserWithUsername(
            @RequestParam(name = "username") String username) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        if (frontUser == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            return ResultObject.ok().data("data", frontUser);
        }
    }
    @GetMapping("get-user-sno")
    public ResultObject getUserWithSno(
            @RequestParam(name = "sno") String sno) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("sno", sno);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        if (frontUser == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            return ResultObject.ok().data("data", frontUser);
        }
    }
    @GetMapping("get-user-email")
    public ResultObject getUserWithEmail(
            @RequestParam(name = "email") String email) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("email", email);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        if (frontUser == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            return ResultObject.ok().data("data", frontUser);
        }
    }
    @GetMapping("get-user-phone")
    public ResultObject getUserWithPhone(
            @RequestParam(name = "phone") String phone) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        if (frontUser == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            return ResultObject.ok().data("data", frontUser);
        }
    }

    @GetMapping("has-user-username")
    public ResultObject hasUserUsername(
            @RequestParam(name = "username") String username) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        return ResultObject.ok().data("data", frontUser != null);
    }
    @GetMapping("has-user-sno")
    public ResultObject hasUserSno(
            @RequestParam(name = "sno") String sno) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("sno", sno);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        return ResultObject.ok().data("data", frontUser != null);
    }
    @GetMapping("has-user-email")
    public ResultObject hasUserEmail(
            @RequestParam(name = "email") String email) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("email", email);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        return ResultObject.ok().data("data", frontUser != null);
    }
    @GetMapping("has-user-phone")
    public ResultObject hasUserPhone(
            @RequestParam(name = "phone") String phone) {
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        FrontUser frontUser = frontUserService.getOne(wrapper);
        return ResultObject.ok().data("data", frontUser != null);
    }

    /**
     * 更新用户信息
     * @param frontUser
     * @return
     */
    @PostMapping("update-user")
    public ResultObject updateUser (
            @RequestBody FrontUser frontUser) {
        frontUser.setPassword(null);
        if (frontUserService.getById(frontUser.getId()) != null) {
            if (frontUserService.updateById(frontUser)) {
                return ResultObject.ok().data("data", frontUser);
            } else {
                return ResultObject.error().message(ResultMessage.OBJECT_EXISTS_BUT_FAILED_TO_UPDATE);
            }
        } else {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
    }

    /**
     * 根据userId更新用户最后在线时间
     * 没有返回用户时表示用户不存在
     * @param id
     * @return
     */
    @PostMapping("update-user-lastLog-id")
    ResultObject updateUserLastLogById (
            @RequestParam(name = "id") String id) {
        FrontUser savedUser = frontUserService.updateUserLastLog(id);
        if (savedUser == null)
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        else
            return ResultObject.ok().data("data", savedUser);

    }

    /**
     * 用户修改密码
     * @param password
     * @param request
     * @return
     */
    @GetMapping("update-user-password-token")
    public ResultObject updateUserPasswordWithToken (
            @RequestParam(name = "password") String password,
            HttpServletRequest request) {
        String token = request.getHeader("token");
        String userId = JwtUtils.getSubjectFromToken(token);
        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(password))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);

        if (frontUserService.updateUserPasswordWithUserId(userId, password))
            return ResultObject.ok();
        else
            return ResultObject.error();
    }

    // 使用消费者进行删除 消费者 删除该用户时 需要同时删除用户的收藏表 拉黑表 删除用户为最高权限操作，非常规操作 封号才需要操作员
    @GetMapping("delete-user-id")
    public ResultObject deleteUserById (
            @RequestParam(name = "id", required = false) String id) {
        FrontUser frontUser = frontUserService.deleteUserById(id);
        if (frontUser != null) {
            return ResultObject.ok().setDataAndCheckNull("data", frontUser);
        } else {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
    }




}

